package org.goodsmanager.controller;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.goodsmanager.common.Result;
import org.goodsmanager.entity.OperationLog;
import org.goodsmanager.entity.User;
import org.goodsmanager.service.OperationLogService;
import org.goodsmanager.util.ExcelExportUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import java.io.IOException;
import java.io.OutputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 操作日志控制器
 *
 * @author Goods Manager System
 * @version 1.0.0
 */
@Slf4j
@Controller
@RequestMapping("/log")
@RequiredArgsConstructor
public class OperationLogController {

    private final OperationLogService operationLogService;

    /**
     * 操作日志页面
     */
    @GetMapping("/list")
    public String list(HttpSession session) {
        // 检查用户是否登录
        User currentUser = (User) session.getAttribute("currentUser");
        if (currentUser == null) {
            return "redirect:/auth/login";
        }
        
        // 只有管理员可以查看操作日志
        if (currentUser.getRole() == null || !"ADMIN".equalsIgnoreCase(currentUser.getRole())) {
            return "redirect:/dashboard";
        }
        
        return "log/list";
    }

    /**
     * 分页查询操作日志
     */
    @GetMapping("/page")
    @ResponseBody
    public Result page(@RequestParam(defaultValue = "1") int pageNum,
                       @RequestParam(defaultValue = "10") int pageSize,
                       @RequestParam(required = false) String userId,
                       @RequestParam(required = false) String operationType,
                       @RequestParam(required = false) String module,
                       @RequestParam(required = false) String status,
                       @RequestParam(required = false) String startTime,
                       @RequestParam(required = false) String endTime,
                       @RequestParam(required = false) String keyword) {
        try {
            // 转换时间参数
            LocalDateTime start = null;
            LocalDateTime end = null;
            
            // 支持多种日期时间格式
            DateTimeFormatter[] formatters = {
                DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"),
                DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"),
                DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"),
                DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm")
            };
            
            if (startTime != null && !startTime.isEmpty()) {
                // 尝试使用不同的格式解析日期
                for (DateTimeFormatter formatter : formatters) {
                    try {
                        start = LocalDateTime.parse(startTime, formatter);
                        break;
                    } catch (Exception e) {
                        // 继续尝试下一种格式
                    }
                }
                
                // 如果所有格式都失败，尝试只解析日期部分
                if (start == null) {
                    try {
                        LocalDate date = LocalDate.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                        start = date.atStartOfDay();
                    } catch (Exception e) {
                        log.error("无法解析开始时间: {}", startTime);
                    }
                }
            }
            
            if (endTime != null && !endTime.isEmpty()) {
                // 尝试使用不同的格式解析日期
                for (DateTimeFormatter formatter : formatters) {
                    try {
                        end = LocalDateTime.parse(endTime, formatter);
                        break;
                    } catch (Exception e) {
                        // 继续尝试下一种格式
                    }
                }
                
                // 如果所有格式都失败，尝试只解析日期部分
                if (end == null) {
                    try {
                        LocalDate date = LocalDate.parse(endTime, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                        end = date.atTime(LocalTime.MAX);
                    } catch (Exception e) {
                        log.error("无法解析结束时间: {}", endTime);
                    }
                }
            }
            
            // 查询数据
            List<OperationLog> logs = operationLogService.getLogsByPage(
                    pageNum, pageSize, userId, operationType, module, status, start, end, keyword);
            
            // 查询总数
            int total = operationLogService.getLogCount(
                    userId, operationType, module, status, start, end, keyword);
            
            // 构建返回结果
            Map<String, Object> data = new HashMap<>();
            data.put("list", logs);
            data.put("total", total);
            data.put("pageNum", pageNum);
            data.put("pageSize", pageSize);
            data.put("pages", (total + pageSize - 1) / pageSize);
            
            return Result.success(data);
        } catch (Exception e) {
            log.error("分页查询操作日志失败", e);
            return Result.error("查询操作日志失败");
        }
    }

    /**
     * 根据ID查询操作日志详情
     */
    @GetMapping("/{id}")
    @ResponseBody
    public Result getById(@PathVariable String id) {
        try {
            OperationLog operationLog = operationLogService.getLogById(id);
            if (operationLog == null) {
                return Result.error("操作日志不存在");
            }
            return Result.success(operationLog);
        } catch (Exception e) {
            log.error("查询操作日志详情失败, ID: {}", id, e);
            return Result.error("查询操作日志详情失败");
        }
    }

    /**
     * 批量删除操作日志
     */
    @DeleteMapping("/batch")
    @ResponseBody
    public Result batchDelete(@RequestBody List<String> ids) {
        try {
            boolean success = operationLogService.batchDeleteLogs(ids);
            if (success) {
                return Result.success("批量删除成功");
            } else {
                return Result.error("批量删除失败");
            }
        } catch (Exception e) {
            log.error("批量删除操作日志失败", e);
            return Result.error("批量删除操作日志失败");
        }
    }

    /**
     * 清理指定天数之前的日志
     */
    @DeleteMapping("/clean/{days}")
    @ResponseBody
    public Result cleanLogs(@PathVariable int days) {
        try {
            if (days <= 0) {
                return Result.error("天数必须大于0");
            }
            
            boolean success = operationLogService.cleanLogsBefore(days);
            if (success) {
                return Result.success("清理成功");
            } else {
                return Result.error("清理失败");
            }
        } catch (Exception e) {
            log.error("清理操作日志失败", e);
            return Result.error("清理操作日志失败");
        }
    }

    /**
     * 导出操作日志
     */
    @GetMapping("/export")
    public void export(@RequestParam(required = false) String userId,
                       @RequestParam(required = false) String operationType,
                       @RequestParam(required = false) String module,
                       @RequestParam(required = false) String status,
                       @RequestParam(required = false) String startTime,
                       @RequestParam(required = false) String endTime,
                       @RequestParam(required = false) String keyword,
                       HttpServletResponse response) throws IOException {
        try {
            // 转换时间参数
            LocalDateTime start = null;
            LocalDateTime end = null;
            
            // 支持多种日期时间格式
            DateTimeFormatter[] formatters = {
                DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"),
                DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"),
                DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"),
                DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm")
            };
            
            if (startTime != null && !startTime.isEmpty()) {
                // 尝试使用不同的格式解析日期
                for (DateTimeFormatter formatter : formatters) {
                    try {
                        start = LocalDateTime.parse(startTime, formatter);
                        break;
                    } catch (Exception e) {
                        // 继续尝试下一种格式
                    }
                }
                
                // 如果所有格式都失败，尝试只解析日期部分
                if (start == null) {
                    try {
                        LocalDate date = LocalDate.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                        start = date.atStartOfDay();
                    } catch (Exception e) {
                        log.error("无法解析开始时间: {}", startTime);
                    }
                }
            }
            
            if (endTime != null && !endTime.isEmpty()) {
                // 尝试使用不同的格式解析日期
                for (DateTimeFormatter formatter : formatters) {
                    try {
                        end = LocalDateTime.parse(endTime, formatter);
                        break;
                    } catch (Exception e) {
                        // 继续尝试下一种格式
                    }
                }
                
                // 如果所有格式都失败，尝试只解析日期部分
                if (end == null) {
                    try {
                        LocalDate date = LocalDate.parse(endTime, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                        end = date.atTime(LocalTime.MAX);
                    } catch (Exception e) {
                        log.error("无法解析结束时间: {}", endTime);
                    }
                }
            }
            
            // 查询数据
            List<OperationLog> logs = operationLogService.exportLogs(
                    userId, operationType, module, status, start, end, keyword);
            
            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = "操作日志_" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss")) + ".xlsx";
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + java.net.URLEncoder.encode(fileName, "UTF-8"));
            
            // 使用自定义方法导出Excel
            exportOperationLogsToExcel(response.getOutputStream(), logs);
            
            log.info("导出操作日志成功，共{}条记录", logs.size());
        } catch (Exception e) {
            log.error("导出操作日志失败", e);
            response.getWriter().write("导出失败: " + e.getMessage());
        }
    }
    
    /**
     * 自定义操作日志导出方法
     */
    private void exportOperationLogsToExcel(OutputStream outputStream, List<OperationLog> logs) throws IOException {
        // 创建工作簿
        org.apache.poi.ss.usermodel.Workbook workbook = new org.apache.poi.xssf.usermodel.XSSFWorkbook();
        org.apache.poi.ss.usermodel.Sheet sheet = workbook.createSheet("操作日志");
        
        // 创建标题行
        org.apache.poi.ss.usermodel.Row headerRow = sheet.createRow(0);
        String[] headers = {"ID", "用户名", "操作类型", "模块", "描述", "请求URL", "请求方法", 
                           "IP地址", "状态", "执行时间(ms)", "操作时间"};
        
        for (int i = 0; i < headers.length; i++) {
            org.apache.poi.ss.usermodel.Cell cell = headerRow.createCell(i);
            cell.setCellValue(headers[i]);
        }
        
        // 填充数据
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        for (int i = 0; i < logs.size(); i++) {
            org.apache.poi.ss.usermodel.Row row = sheet.createRow(i + 1);
            OperationLog log = logs.get(i);
            
            row.createCell(0).setCellValue(log.getId());
            row.createCell(1).setCellValue(log.getUsername());
            row.createCell(2).setCellValue(log.getOperationTypeText());
            row.createCell(3).setCellValue(log.getModule());
            row.createCell(4).setCellValue(log.getDescription());
            row.createCell(5).setCellValue(log.getRequestUrl());
            row.createCell(6).setCellValue(log.getRequestMethod());
            row.createCell(7).setCellValue(log.getIpAddress());
            row.createCell(8).setCellValue(log.getStatusText());
            row.createCell(9).setCellValue(log.getExecutionTime());
            row.createCell(10).setCellValue(log.getCreatedAt() != null ? log.getCreatedAt().format(formatter) : "");
        }
        
        // 自动调整列宽
        for (int i = 0; i < headers.length; i++) {
            sheet.autoSizeColumn(i);
        }
        
        // 写入输出流
        workbook.write(outputStream);
        workbook.close();
    }

    /**
     * 获取操作统计数据
     */
    @GetMapping("/statistics")
    @ResponseBody
    public Result getStatistics(@RequestParam(required = false) String startTime,
                               @RequestParam(required = false) String endTime) {
        try {
            // 转换时间参数
            LocalDateTime start = null;
            LocalDateTime end = null;
            
            // 支持多种日期时间格式
            DateTimeFormatter[] formatters = {
                DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"),
                DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"),
                DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"),
                DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm")
            };
            
            if (startTime != null && !startTime.isEmpty()) {
                // 尝试使用不同的格式解析日期
                for (DateTimeFormatter formatter : formatters) {
                    try {
                        start = LocalDateTime.parse(startTime, formatter);
                        break;
                    } catch (Exception e) {
                        // 继续尝试下一种格式
                    }
                }
                
                // 如果所有格式都失败，尝试只解析日期部分
                if (start == null) {
                    try {
                        LocalDate date = LocalDate.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                        start = date.atStartOfDay();
                    } catch (Exception e) {
                        log.error("无法解析开始时间: {}", startTime);
                    }
                }
            }
            
            if (endTime != null && !endTime.isEmpty()) {
                // 尝试使用不同的格式解析日期
                for (DateTimeFormatter formatter : formatters) {
                    try {
                        end = LocalDateTime.parse(endTime, formatter);
                        break;
                    } catch (Exception e) {
                        // 继续尝试下一种格式
                    }
                }
                
                // 如果所有格式都失败，尝试只解析日期部分
                if (end == null) {
                    try {
                        LocalDate date = LocalDate.parse(endTime, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                        end = date.atTime(LocalTime.MAX);
                    } catch (Exception e) {
                        log.error("无法解析结束时间: {}", endTime);
                    }
                }
            }
            
            // 默认查询最近7天的数据
            if (start == null) {
                start = LocalDateTime.now().minusDays(7);
            }
            if (end == null) {
                end = LocalDateTime.now();
            }
            
            // 查询统计数据
            List<Map<String, Object>> operationTypeStats = operationLogService.countByOperationType(start, end);
            List<Map<String, Object>> moduleStats = operationLogService.countByModule(start, end);
            List<Map<String, Object>> userStats = operationLogService.countByUser(start, end, 10);
            
            // 构建返回结果
            Map<String, Object> data = new HashMap<>();
            data.put("operationTypeStats", operationTypeStats);
            data.put("moduleStats", moduleStats);
            data.put("userStats", userStats);
            
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取操作统计数据失败", e);
            return Result.error("获取操作统计数据失败");
        }
    }
}